enum BoundaryType
{
	Open,
	Slip,
	Zero
};

enum NumericalScheme
{
	BackwardEuler,
	CrankNicolson,
	ForwardEuler,
	MacCormack,
	RungeKutta2,
	RungeKutta3,
	RungeKutta4,
	SemiLagrange
};

// boundary conditions
template<typename T>
void applyBoundaryX(int nx, int ny, int nz, T bc, T *f);
template<typename T>
void applyBoundaryY(int nx, int ny, int nz, T bc, T *f);
template<typename T>
void applyBoundaryZ(int nx, int ny, int nz, T bc, T *f);

// common PDE operators
template<typename T>
void convect(int nx, int ny, int nz, T dx, T dt, T *u, T *v, T *w, T *f, T *fout, const FieldType type, const NumericalScheme scheme);
template<typename T>
void solveHeatEquation(int nx, int ny, int nz, T dx, T dt, T kappa, T *u, T *uout, int its);
template<typename T>
void solvePoissonEquation(int nx, int ny, int nz, T dx, T *f, T *u, int its);
template<typename T>
void project(int nx, int ny, int nz, T dx, T *u, T *v, T *w, T *p);

// flow operators
template<typename T>
void gravity(int nx, int ny, int nz, T dx, T dt, T g, T famb, T *f, T *v);
template<typename T>
void turbulence(int nx, int ny, int nz, T dx, T eps, T *cx, T *cy, T *cz, T *cn, T *fx, T *fy, T *fz);
template<typename T>
void accelerate(int nx, int ny, int nz, T dx, T dt, T *fx, T *fy, T *fz, T *u, T *v, T *w);
template<typename T>
void reaction(int nx, int ny, int nz, T dx, T dt, T burn, T cool, T tamb, T tmax, T *f, T *s, T *t);

// particle operators
template<typename T>
void convectParticles(int nx, int ny, int nz, T dx, T dt, T *u, T *v, T *w, int np, float3 *p);
